﻿using System;
using System.Collections.Generic;
using NUnit.Framework;
using Rhino.Mocks;
using StrategicDataSystems.Cloud.Monitoring.Configuration;
using StrategicDataSystems.Cloud.Monitoring.HostedServices;
using StrategicDataSystems.Cloud.Monitoring.UI;
using StrategicDataSystems.Cloud.Monitoring.UI.ViewModels;
using StrategicDataSystems.Cloud.Monitoring.UI.Services;
using System.Threading;

namespace StrategicDataSystems.Cloud.Monitoring.Tests.Given_A_SysTrayViewModel
{
    [TestFixture]
    public class When_KillDeploymentCommand_Is_Fired
    {

        [Test]
        public void Should_Fire_Kill_Command_For_Deployment()
        {
            var mockHostedServiceGateway = MockRepository.GenerateMock<IHostedServiceManagement>();
            var stubNotificationService = MockRepository.GenerateStub<INotificationService>();
            var stubNetPresenceService = MockRepository.GenerateStub<INetPresenceService>();
            var stubTimerService = MockRepository.GenerateStub<ITimerService>();

            var deploymentToKill = new Deployment("Staging", new Uri("http://example.com"), "v1.2", "Stopped", "service1");

            var fakeHostedServices = new List<HostedService>() { 
		            new HostedService("service1", new Uri("http://management.net"), 
		                new List<Deployment> () {
                            new Deployment("Production", new Uri("http://exmaple.com"), "v1.0", "Running", "service1"),
                            deploymentToKill} )};

            Settings settings = new Settings();

            mockHostedServiceGateway.Stub(
                x => x.GetHostedServicesForSubscription(settings.SubscriptionId, settings.CertificateThumbprint))
                .Return(fakeHostedServices);
            stubNetPresenceService.Stub(x => x.InternetConnectionIsAvailable()).Return(true);

            SysTrayViewModel viewModel = new SysTrayViewModel(mockHostedServiceGateway, settings, stubNotificationService, stubTimerService, stubNetPresenceService);

            ((RelayCommand)viewModel.KillDeploymentCommand).Execute(deploymentToKill);

            //Wait for background thread to complete
            Thread.Sleep(10);

            mockHostedServiceGateway.AssertWasCalled(x => x.KillHostedServiceDeployment(TestSettings.TestSubscriptionId, TestSettings.TestCertificateThumbprint, "service1", "Staging"));
        }

        [Test]
        public void Should_Alert_User_Of_Kill_Command_Sent()
        {
            var stubHostedServiceGateway = MockRepository.GenerateStub<IHostedServiceManagement>();
            var mockNotificationService = MockRepository.GenerateMock<INotificationService>();
            var stubNetPresenceService = MockRepository.GenerateStub<INetPresenceService>();
            var stubTimerService = MockRepository.GenerateStub<ITimerService>();

            var deploymentToKill = new Deployment("Staging", new Uri("http://example.com"), "v1.2", "Stopped", "service1");

            var fakeHostedServices = new List<HostedService>() { 
		            new HostedService("service1", new Uri("http://management.net"), 
		                new List<Deployment> () {
                            new Deployment("Production", new Uri("http://exmaple.com"), "v1.0", "Running", "service1"),
                            deploymentToKill} )};

            Settings settings = new Settings();

            stubHostedServiceGateway.Stub(
                x => x.GetHostedServicesForSubscription(settings.SubscriptionId, settings.CertificateThumbprint))
                .Return(fakeHostedServices);
            stubNetPresenceService.Stub(x => x.InternetConnectionIsAvailable()).Return(true);

            SysTrayViewModel viewModel = new SysTrayViewModel(stubHostedServiceGateway, settings, mockNotificationService, stubTimerService, stubNetPresenceService);

            ((RelayCommand)viewModel.KillDeploymentCommand).Execute(deploymentToKill);

            //Wait for background thread to complete.
            Thread.Sleep(10);

            mockNotificationService.AssertWasCalled(x => x.NotifyUserOfKillCommand(1));
        }

        [Test]
        public void Should_Ignore_Non_Deployment_Objects_Passed_In()
        {
            var stubHostedServiceGateway = MockRepository.GenerateStub<IHostedServiceManagement>();
            var mockNotificationService = MockRepository.GenerateMock<INotificationService>();
            var stubNetPresenceService = MockRepository.GenerateStub<INetPresenceService>();
            var stubTimerService = MockRepository.GenerateStub<ITimerService>();

            var fakeHostedServices = new List<HostedService>() { 
		            new HostedService("service1", new Uri("http://management.net"), 
		                new List<Deployment> () {
                            new Deployment("Production", new Uri("http://exmaple.com"), "v1.0", "Running", "service1")})};

            Settings settings = new Settings();

            stubHostedServiceGateway.Stub(
                x => x.GetHostedServicesForSubscription(settings.SubscriptionId, settings.CertificateThumbprint))
                .Return(fakeHostedServices);
            stubNetPresenceService.Stub(x => x.InternetConnectionIsAvailable()).Return(true);

            SysTrayViewModel viewModel = new SysTrayViewModel(stubHostedServiceGateway, settings, mockNotificationService, stubTimerService, stubNetPresenceService);

            ((RelayCommand)viewModel.KillDeploymentCommand).Execute(new object());

            mockNotificationService.AssertWasNotCalled(x => x.NotifyUserOfKillCommand(1));
        }

        [Test]
        public void Should_Ignore_Null_Passed_In()
        {
            var stubHostedServiceGateway = MockRepository.GenerateStub<IHostedServiceManagement>();
            var stubNetPresenceService = MockRepository.GenerateStub<INetPresenceService>();
            var mockNotificationService = MockRepository.GenerateMock<INotificationService>();
            var stubTimerService = MockRepository.GenerateStub<ITimerService>();

            var fakeHostedServices = new List<HostedService>() { 
		            new HostedService("service1", new Uri("http://management.net"), 
		                new List<Deployment> () {
                            new Deployment("Production", new Uri("http://exmaple.com"), "v1.0", "Running", "service1")})};

            Settings settings = new Settings();

            stubHostedServiceGateway.Stub(
                x => x.GetHostedServicesForSubscription(settings.SubscriptionId, settings.CertificateThumbprint))
                .Return(fakeHostedServices);
            stubNetPresenceService.Stub(x => x.InternetConnectionIsAvailable()).Return(true);

            SysTrayViewModel viewModel = new SysTrayViewModel(stubHostedServiceGateway, settings, mockNotificationService, stubTimerService, stubNetPresenceService);

            ((RelayCommand)viewModel.KillDeploymentCommand).Execute(null);

            mockNotificationService.AssertWasNotCalled(x => x.NotifyUserOfKillCommand(1));
        }

        [Test]
        public void Should_Alert_User_If_No_Internet_Connection_Is_Present()
        {
            var stubHostedServiceGateway = MockRepository.GenerateStub<IHostedServiceManagement>();
            var stubNetPresenceService = MockRepository.GenerateStub<INetPresenceService>();
            var mockNotificationService = MockRepository.GenerateMock<INotificationService>();
            var stubTimerService = MockRepository.GenerateStub<ITimerService>();

            Settings settings = new Settings();

            stubNetPresenceService.Stub(x => x.InternetConnectionIsAvailable()).Return(false);

            SysTrayViewModel viewModel = new SysTrayViewModel(stubHostedServiceGateway, settings, mockNotificationService, stubTimerService, stubNetPresenceService);

            ((RelayCommand)viewModel.KillDeploymentCommand).Execute(null);

            mockNotificationService.AssertWasCalled(x => x.NotifyUserOfLostConnection());
        }
    }
}
